package com.racetime.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author : Ice'Clean
 * @date : 2021-05-01
 *
 * Service 层动态代理实现类，实现：
 * 1. 创建数据库连接对象
 * 2. 统一事务提交
 * 3. 事务回滚处理
 * 4. 关闭数据库连接对象
 */
public class ServiceAgent implements InvocationHandler {

    private Object object;

    /**
     * 动态获取接受代理的对象
     * @param object 受代理对象
     */
    public ServiceAgent(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        // 存放返回值
        Object result = null;
        Connection conn = null;

        try {
            // 获取数据库连接对象，并设置为手动提交
            conn = JdbcUtil.getConnection();
            conn.setAutoCommit(false);

            // 执行具体业务逻辑
            result = method.invoke(object, args);

            // 没出问题的话则提交事务
            conn.commit();
        } catch (SQLException sqlException) {

            try {
                // 数据库操作异常，回滚事务
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            sqlException.printStackTrace();

        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        } finally {
            // 最后关闭数据库连接
            JdbcUtil.closeAll(conn, null, null, null);
        }

        return result;
    }

    /**
     * 获取执行代理的对象
     * @return 执行代理的对象实例
     */
    public Object getAgent() {
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
    }
}
